#include "piechartwidget.h"
#include <QMouseEvent>
#include <QToolTip>
#include <cmath>
#include <algorithm>

// 兼容性函数：角度转弧度
static inline double degreesToRadians(double degrees)
{
    return degrees * M_PI / 180.0;
}

PieChartWidget::PieChartWidget(QWidget *parent)
    : QWidget(parent)
    , m_showLegend(true)
    , m_showPercentage(true)
    , m_highlightEnabled(true)
    , m_pieRadius(80)
    , m_legendPosition(Right)
    , highlightedSlice(-1)
{
    // 初始化四个数据切片
    slices.resize(4);

    // 设置默认颜色
    QVector<QColor> defaultColors = {
        QColor(65, 105, 225),   // 皇家蓝
        QColor(220, 20, 60),    // 猩红
        QColor(50, 205, 50),    // 酸橙绿
        QColor(255, 165, 0)     // 橙色
    };

    for (int i = 0; i < 4; ++i) {
        slices[i].color = defaultColors[i];
        slices[i].label = QString("数据 %1").arg(i + 1);
        slices[i].value = 25.0; // 默认等分
    }

    calculatePercentages();

    // 设置字体
    titleFont = font();
    titleFont.setBold(true);
    titleFont.setPointSize(titleFont.pointSize() + 2);

    legendFont = font();
    legendFont.setPointSize(legendFont.pointSize() - 1);

    setMouseTracking(true);
    setMinimumHeight(200);

}

void PieChartWidget::setData(double value1, double value2, double value3, double value4)
{
    slices[0].value = value1;
    slices[1].value = value2;
    slices[2].value = value3;
    slices[3].value = value4;

    calculatePercentages();
    update();
}

void PieChartWidget::setData(const QVector<double> &values)
{
    if (values.size() >= 4) {
        for (int i = 0; i < 4; ++i) {
            slices[i].value = values[i];
        }
        calculatePercentages();
        update();
    }
}

void PieChartWidget::setLabels(const QString &label1, const QString &label2,
                               const QString &label3, const QString &label4)
{
    slices[0].label = label1;
    slices[1].label = label2;
    slices[2].label = label3;
    slices[3].label = label4;
    update();
}

void PieChartWidget::setLabels(const QVector<QString> &labels)
{
    if (labels.size() >= 4) {
        for (int i = 0; i < 4; ++i) {
            slices[i].label = labels[i];
        }
        update();
    }
}

void PieChartWidget::setColors(const QColor &color1, const QColor &color2,
                               const QColor &color3, const QColor &color4)
{
    slices[0].color = color1;
    slices[1].color = color2;
    slices[2].color = color3;
    slices[3].color = color4;
    update();
}

void PieChartWidget::setColors(const QVector<QColor> &colors)
{
    if (colors.size() >= 4) {
        for (int i = 0; i < 4; ++i) {
            slices[i].color = colors[i];
        }
        update();
    }
}

void PieChartWidget::setTitle(const QString &title)
{
    chartTitle = title;
    update();
}

QString PieChartWidget::title() const
{
    return chartTitle;
}

void PieChartWidget::setShowLegend(bool show)
{
    m_showLegend = show;
    update();
}

bool PieChartWidget::showLegend() const
{
    return m_showLegend;
}

void PieChartWidget::setPieRadius(int radius)
{
    m_pieRadius = radius;
    update();
}

int PieChartWidget::pieRadius() const
{
    return m_pieRadius;
}

void PieChartWidget::setLegendPosition(LegendPosition position)
{
    m_legendPosition = position;
    update();
}

PieChartWidget::LegendPosition PieChartWidget::legendPosition() const
{
    return m_legendPosition;
}

void PieChartWidget::setShowPercentage(bool show)
{
    m_showPercentage = show;
    update();
}

bool PieChartWidget::showPercentage() const
{
    return m_showPercentage;
}

void PieChartWidget::setHighlightEnabled(bool enable)
{
    m_highlightEnabled = enable;
    if (!enable) {
        highlightedSlice = -1;
        for (auto &slice : slices) {
            slice.highlighted = false;
        }
    }
    update();
}

bool PieChartWidget::highlightEnabled() const
{
    return m_highlightEnabled;
}

void PieChartWidget::clear()
{
    for (auto &slice : slices) {
        slice.value = 0;
        slice.percentage = 0;
    }
    calculatePercentages();
    update();
}

void PieChartWidget::updateChart()
{
    calculatePercentages();
    update();
}

void PieChartWidget::calculatePercentages()
{
    double total = 0;
    for (const auto &slice : slices) {
        total += slice.value;
    }

    if (total > 0) {
        double startAngle = 0;
        for (auto &slice : slices) {
            slice.percentage = (slice.value / total) * 100.0;
            slice.startAngle = startAngle;
            slice.spanAngle = (slice.value / total) * 360.0 * 16;
            startAngle += slice.spanAngle;
        }
    }
}

void PieChartWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    // 绘制背景
    painter.fillRect(rect(), palette().window());

    // 绘制标题
    if (!chartTitle.isEmpty()) {
        painter.setFont(titleFont);
        painter.setPen(palette().windowText().color());
        QRect titleRect = rect().adjusted(-10, 0, -5, -5);
        painter.drawText(titleRect, Qt::AlignTop | Qt::AlignHCenter, chartTitle);
    }

    // 绘制饼图
    drawPieChart(painter);

    // 绘制图例
    if (m_showLegend) {
         drawLegend(painter);
     }
}

void PieChartWidget::drawPieChart(QPainter &painter)
{
    QPoint center = getPieCenter();

    for (int i = 0; i < slices.size(); ++i) {
        const auto &slice = slices[i];

        QColor color = slice.color;
        if (slice.highlighted) {
            color = color.lighter(130); // 高亮时变亮
        }

        painter.setBrush(color);
        painter.setPen(QPen(palette().windowText(), 1));

        QRect pieRect(center.x() - m_pieRadius, center.y() - m_pieRadius,
                      m_pieRadius * 2, m_pieRadius * 2);

        painter.drawPie(pieRect, slice.startAngle, slice.spanAngle);

        // 绘制百分比文本
        if (m_showPercentage && slice.percentage > 5) {
            double midAngle = (slice.startAngle + slice.spanAngle / 2.0) / 16.0;
            double radian = degreesToRadians(midAngle);
            int textRadius = m_pieRadius * 0.7;

            int x = center.x() + textRadius * cos(radian);
            int y = center.y() - textRadius * sin(radian);

            QString percentageText = QString::number(slice.percentage, 'f', 1) + "%";

            //painter.setPen(palette().windowText(), 1);
            QFontMetrics fm(painter.font());
            int textWidth = fm.horizontalAdvance(percentageText);
            QRect textRect(x - textWidth / 2, y - fm.height() / 2,
                           textWidth, fm.height());

            painter.drawText(textRect, Qt::AlignCenter, percentageText);
        }
    }
}

void PieChartWidget::drawLegend(QPainter &painter)
{
    painter.setFont(legendFont);
    QFontMetrics fm(legendFont);
    int legendItemHeight = fm.height() + 5;
    int colorBoxSize = fm.height() - 2;
    int margin = 10;

    int legendWidth = 0;
    for (const auto &slice : slices) {
        int textWidth = fm.horizontalAdvance(slice.label);
        if (m_showPercentage) {
            textWidth += fm.horizontalAdvance(QString(" (100.0%)"));
        }
        legendWidth = qMax(legendWidth, textWidth + colorBoxSize + 15);
    }

    QRect legendRect;
    QPoint center = getPieCenter();

    switch (m_legendPosition) {
    case Right:
        legendRect = QRect(center.x() + m_pieRadius + margin, center.y() - m_pieRadius,
                           legendWidth, m_pieRadius * 2);
        break;
    case Bottom:
        legendRect = QRect(center.x() - m_pieRadius, center.y() + m_pieRadius + margin,
                           m_pieRadius * 2, slices.size() * legendItemHeight);
        break;
    case Top:
        legendRect = QRect(center.x() - m_pieRadius, center.y() - m_pieRadius - margin - slices.size() * legendItemHeight,
                           m_pieRadius * 2, slices.size() * legendItemHeight);
        break;
    case Left:
        legendRect = QRect(center.x() - m_pieRadius - margin - legendWidth, center.y() - m_pieRadius,
                           legendWidth, m_pieRadius * 2);
        break;
    }

    painter.setPen(QPen(palette().windowText(), 1));
    painter.setBrush(palette().base());
    painter.drawRect(legendRect);

    int y = legendRect.top() + 5;
    for (int i = 0; i < slices.size(); ++i) {
        const auto &slice = slices[i];

        // 绘制颜色方块
        QRect colorRect(legendRect.left() + 5, y, colorBoxSize, colorBoxSize);
        painter.setBrush(slice.color);
        painter.drawRect(colorRect);

        // 绘制文本
        QString legendText = slice.label;
        if (m_showPercentage) {
            legendText += QString(" (%1%)").arg(slice.percentage, 0, 'f', 1);
        }

        //painter.setPen(palette().windowText());
        painter.drawText(legendRect.left() + colorBoxSize + 10, y + fm.ascent(), legendText);

        y += legendItemHeight;
    }
}

QPoint PieChartWidget::getPieCenter() const
{
    int availableWidth = width();
    int availableHeight = height();

    if (m_showLegend && m_legendPosition == Right) {
        availableWidth -= 100; // 为右侧图例预留空间
    } else if (m_showLegend && m_legendPosition == Left) {
        availableWidth -= 100;
    }

    return QPoint(availableWidth / 2, availableHeight / 2);
}

void PieChartWidget::mouseMoveEvent(QMouseEvent *event)
{
    if (!m_highlightEnabled) {
        QWidget::mouseMoveEvent(event);
        return;
    }

    QPoint pos = event->pos();
    QPoint center = getPieCenter();

    // 检查鼠标是否在饼图范围内
    int dx = pos.x() - center.x();
    int dy = pos.y() - center.y();
    double distance = sqrt(dx * dx + dy * dy);

    if (distance <= m_pieRadius) {
        // 计算角度
        double angle = atan2(dy, dx) * 180.0 / M_PI;
        if (angle < 0) angle += 360;

        // 找到对应的切片
        int foundSlice = -1;
        for (int i = 0; i < slices.size(); ++i) {
            double startAngle = slices[i].startAngle / 16.0;
            double endAngle = startAngle + slices[i].spanAngle / 16.0;

            if (angle >= startAngle && angle <= endAngle) {
                foundSlice = i;
                break;
            }
        }

        updateHighlight(foundSlice);

        // 显示工具提示
        if (foundSlice >= 0) {
            QString tooltip = QString("%1: %2 (%3%)")
            .arg(slices[foundSlice].label)
                .arg(slices[foundSlice].value)
                .arg(slices[foundSlice].percentage, 0, 'f', 1);
            QToolTip::showText(event->globalPos(), tooltip, this);
        } else {
            QToolTip::hideText();
        }
    } else {
        updateHighlight(-1);
        QToolTip::hideText();
    }

    QWidget::mouseMoveEvent(event);
}

void PieChartWidget::leaveEvent(QEvent *event)
{
    Q_UNUSED(event);
    updateHighlight(-1);
    QToolTip::hideText();
}

void PieChartWidget::updateHighlight(int sliceIndex)
{
    if (highlightedSlice != sliceIndex) {
        if (highlightedSlice >= 0 && highlightedSlice < slices.size()) {
            slices[highlightedSlice].highlighted = false;
        }

        highlightedSlice = sliceIndex;

        if (highlightedSlice >= 0 && highlightedSlice < slices.size()) {
            slices[highlightedSlice].highlighted = true;
        }

        update();
    }
}

QSize PieChartWidget::sizeHint() const
{
    return QSize(400, 300);
}

QSize PieChartWidget::minimumSizeHint() const
{
    return QSize(200, 150);
}
